#include "stdafx.h"
#include "libraries.h"

#include "Application.h"
#include "Filesystem.h"

#include "VectorBatch.h"
#include "SpriteBatch.h"

#include "Demo.h"

#include "Textgen.h"
#include "Ribbons.h"
#include "Markov.h"
#include "Snowflake.h"

#include "DisplayModeDialog.h"

using namespace Cvekas;

const float width = 1024.0f;
const float height = 576.0f;

class Celerity: public Application
{
public:
	Celerity(HINSTANCE instance, const std::string& name, const std::string& log_filename)
		: Application(instance, name, log_filename)
	{
	}

	virtual ~Celerity()
	{
	}

	virtual void initVideoDevice()
	{
		DeviceCapsPtr caps = video_device->getCaps(D3DDEVTYPE_HAL);
		if(caps->getPSVersion() < DeviceCaps::ps2_0 || caps->getVSVersion() < DeviceCaps::vs2_0)
		{
			MessageBox(NULL, "Your graphics card sucks.", "ERROR", MB_OK);
			return;
		}

		settings->insert("video", VideoSettings());
		VideoSettings& video_settings = static_cast<VideoSettings&>((*settings)["video"]);

		textgenInit();
		
		if(!showDisplaymodeDialog(video_device->getModes(), video_settings))
			return;

		window = WindowPtr(new Window(instance, name));
		window->showCursor(false);
		video_device->init(window);
		video_device->setProjectionMatrix(Matrix::perspective(pi / 4.0f, width / height, 0.2f, 100.0f));
		video_device->setAspectRatio(width / height);
	}

	virtual void init()
	{
		SoundPtr soundtrack = sound_manager->loadStream("demogroove4", Filesystem::redirect("demogroove4.ogg"));

		vector_batch = VectorBatchPtr(new VectorBatch(main_renderer, (uint)width, (uint)height));
		vector_batch->setVirtualResolution(uint(width), uint(height));
		sprite_batch = SpriteBatchPtr(new SpriteBatch(main_renderer, (uint)width, (uint)height));
		sprite_batch->setVirtualResolution(uint(width), uint(height));

		powell = BitmapFontPtr(new BitmapFont(sprite_batch, Filesystem::redirect("powell.fnt"), 1000));

		
		
		demo = DemoPtr(new Demo(soundtrack));

		RibbonsPtr ribbons(new Ribbons(main_renderer, vector_batch, sprite_batch, powell));
		MarkovPtr markov(new Markov(main_renderer, vector_batch, sprite_batch, powell));
		SnowflakePtr snowflake(new Snowflake(main_renderer, vector_batch, sprite_batch, powell));

		demo->add(0, 0.0f, 21.0f, markov);
		demo->add(0, 21.02f, 44.0f, ribbons);
		demo->add(0, 44.02f, 78.0f, snowflake);
		demo->seal();

	}

	virtual bool update()
	{
		static bool first_time = true;
		if(first_time)
		{
			loading_finished_t = Timer::getTimeMs();
			first_time = false;
		}
		// Delay starting demo by 1 second
		static bool is_playing = false;
		if(!is_playing && (Timer::getTimeMs() > (loading_finished_t + 1000)))
		{
			is_playing = true;
			Timer::reset();
			demo->play();
			//demo->setTime(60.01f);
		}
		
		input->getKeyboard()->update();

		return demo->update();
	}

	virtual bool render()
	{
		bool result = demo->render();

		return result;
	}

private:
	DemoPtr demo;

	VectorBatchPtr vector_batch;
	SpriteBatchPtr sprite_batch;
	BitmapFontPtr powell;

	int loading_finished_t;
};

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int nShowCmd)
{
	try
	{
		Filesystem::init("celerity_data\\");
		Celerity app(hInstance, "Celerity", Filesystem::redirect("celerity.log"));
		app.run();
	}
	catch (std::exception& e)
	{
		MessageBox(NULL, e.what(), "Fatal error", NULL);
	}
	return 0;
}
